<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="my-div">普通 div（外部内容）</div>

    <script>
        const div = document.querySelector('#my-div');

        // 附加 Shadow DOM（mode: 'open' 表示允许外部访问）
        const shadowRoot = div.attachShadow({ mode: 'open' });

        // 在 Shadow DOM 内部添加内容
        shadowRoot.innerHTML = `
    <style>
      p { color: red; }  /* 仅作用于 Shadow DOM 内部 */
    </style>
    <p>这是 Shadow DOM 里的内容！</p>
  `;
    </script>
</body>

<!--
这里  普通 div（外部内容） 不展示,但是你可以



---

### **1. 自定义标签的本质**
当你在 HTML 中直接写 `<my-tag>`，浏览器的行为如下：
```javascript
// 浏览器底层处理逻辑（伪代码）
class HTMLUnknownElement extends HTMLElement {} // 所有未知标签的基类
customElements.define('my-tag', HTMLUnknownElement); // 自动注册为“未知标签”
```
- **相当于继承 `HTMLElement`**：是的，但继承的是最基础的 `HTMLUnknownElement`（无任何扩展）。
- **默认方法不可修改**：完全正确！你无法干预它的生命周期、属性监听等，就像你不能修改 `Object.prototype.toString` 的默认行为。

---

### **2. vs 正式 Web Components 的差异**
通过 `customElements.define` 注册的组件：
```javascript
class MyButton extends HTMLElement { // 显式继承
  constructor() { 
    super(); // 可自由扩展逻辑
    this.addEventListener('click', this.handleClick); 
  }
  handleClick() { /* 自定义方法 */ }
}
customElements.define('my-button', MyButton); // 主动注册
```
| 能力                | 自定义标签 (`<my-tag>`) | 正式 Web Component (`MyButton`) |
|---------------------|------------------------|--------------------------------|
| **原型链**           | `HTMLUnknownElement`   | 你定义的子类（如 `MyButton`）    |
| **扩展方法**         | ❌ 不可添加            | ✅ 可添加 `handleClick` 等方法   |
| **生命周期钩子**     | ❌ 无                  | ✅ 可定义 `connectedCallback` 等 |
| **属性监听**         | ❌ 无                  | ✅ 通过 `observedAttributes` 实现 |

---

### **3. 类比：操作系统权限**
| 角色                | 自定义标签                 | Web Components                |
|---------------------|--------------------------|-------------------------------|
| **权限级别**         | 普通用户（仅基础功能）      | 管理员（可修改系统配置）        |
| **能否装软件**       | ❌ 只能使用预装应用         | ✅ 可安装任意程序               |
| **能否改系统设置**   | ❌ 不能                   | ✅ 可修改注册表/配置文件         |

- 自定义标签就像一台**出厂默认的手机**，你只能用预装功能。
- Web Components 是**开发者模式**，允许你刷机、改内核。

---

### **4. 关键技术验证**
#### **测试 1：自定义标签能否添加方法？**
```html
<my-tag id="tag"></my-tag>
<script>
  const tag = document.querySelector('#tag');
  tag.sayHello = () => console.log('Hello'); // 可以动态添加属性（但这是 JS 对象的通用特性，不是组件能力）
  console.log(tag instanceof HTMLUnknownElement); // true
</script>
```
- **动态添加的属性**只是 JS 对象的特性，和组件化无关。

#### **测试 2：能否拦截生命周期？**
```javascript
// 尝试监听自定义标签的属性变化（失败）
document.querySelector('my-tag').attributeChangedCallback = () => {
  console.log('属性变化'); // 永远不会执行
};
```
- **`HTMLUnknownElement` 没有开放生命周期钩子**。

---

### **5. 何时用自定义标签？**
#### **✅ 适用场景**
- 快速原型开发（不需要复用）。
- 作为 CSS 选择器钩子（替代 `.class`）。
- 配合 Vue/React 等框架的编译时组件（框架会处理逻辑）。

#### **❌ 不适用场景**
- 需要内部状态管理（如 `<my-counter>`）。
- 需要响应式属性（如 `<my-tabs active="1">`）。
- 需要跨项目复用的组件库。

---

### **6. 总结**
- **你的理解正确**：普通自定义标签相当于“只读”的 `HTMLElement`，无法深度定制。
- **Web Components 的价值**：提供完整的**组件开发权限**，包括：
  - 方法扩展
  - 生命周期控制
  - 属性监听
  - Shadow DOM 深度集成
- **就像 `class` 和 `Object.create` 的区别**：前者可定义方法，后者只能操作现有属性。


 -->

</html>